package cn.gok.springsecuritydemo01.contoller;

import cn.gok.springsecuritydemo01.dao.UserDAO1;
import cn.gok.springsecuritydemo01.entity.User1;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.context.SecurityContextImpl;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.Map;

/**

 */
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserDAO1 userDAO;

    @PostMapping("/addUser")
    public Map<String,Object> addUser(User1 user1){
        //存入数据库之前，对密码进行加密
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        String  newPassword = encoder.encode(user1.getPassword());
        user1.setPassword(newPassword);

        //设置用户状态值
        user1.setStatus(1);

        //存入数据库
        userDAO.insert(user1);

        //返回结果
        Map<String, Object> map = new HashMap<>();
        map.put("code","200");
        map.put("msg","注册成功");

        return map;
    }

    /**
        获取用户信息方式1：
            Spring Security会将登录成功后的用户信息存放在一个Authentication对象中，
            然后自动存入Session、SecurityContext中

            session中其key为： SPRING_SECURITY_CONTEXT

     */
    @GetMapping("/getUserInfo1")
    public Map<String,Object> getUserInfo1(HttpSession httpSession){
        SecurityContextImpl securityContextImpl  = (SecurityContextImpl)httpSession.getAttribute("SPRING_SECURITY_CONTEXT");
        Authentication authentication = securityContextImpl.getAuthentication();

        /*
            Spring Security  提供的UserDetails的默认实现类
                        org.springframework.security.core.userdetails.User
                    只存放了少量的用户信息： 用户名 、权限列表
         */
        UserDetails userDetails = (UserDetails)authentication.getPrincipal();


        String username = userDetails.getUsername();


        //依据用户名从数据库查找信息
        QueryWrapper<User1> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", username);
        User1 userInfo = userDAO.selectOne(queryWrapper);

        Map<String, Object> map = new HashMap<>();
        map.put("code","200");
        map.put("data",userInfo);

        return map;
    }


    /**
     * 获取用户信息方式2： 直接从SecurityContext中取出用户信息对象 Authentication
     */
    @GetMapping("/getUserInfo2")
    public Map<String,Object> getUserInfo2(){

        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

        UserDetails userDetails = (UserDetails)authentication.getPrincipal();


        String username = userDetails.getUsername();

        //依据用户名从数据库查找信息
        QueryWrapper<User1> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", username);
        User1 userInfo = userDAO.selectOne(queryWrapper);

        Map<String, Object> map = new HashMap<>();
        map.put("code","200");
        map.put("data",userInfo);

        return map;
    }


    /**
     * 获取用户信息方式3： 直接让Spring 传Authentication对象
     */
    @GetMapping("/getUserInfo3")
    public Map<String,Object> getUserInfo3(Authentication authentication){

        UserDetails userDetails = (UserDetails)authentication.getPrincipal();

        String username = userDetails.getUsername();

        //依据用户名从数据库查找信息
        QueryWrapper<User1> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", username);
        User1 userInfo = userDAO.selectOne(queryWrapper);

        Map<String, Object> map = new HashMap<>();
        map.put("code","200");
        map.put("data",userInfo);

        return map;
    }




}
